package com.basic.library.base

import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.Editable
import android.text.SpannableString
import android.text.Spanned
import android.text.TextWatcher
import android.text.style.AbsoluteSizeSpan
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.basic.library.R
import com.basic.library.base.ConstConfig.splitDate1
import com.basic.library.utils.CommonUtils
import com.basic.library.utils.DateUtils
import com.basic.library.utils.SpannedBean
import com.basic.library.utils.SpannedUtil
import com.basic.library.view.MEditText
import com.google.gson.Gson
import com.maning.mndialoglibrary.config.MDialogConfig
import java.util.*

/**
 * @author yj
 * @description 常量配置
 */
object ConstConfig {
    val dConfig = MDialogConfig.Builder()
        .isCanceledOnTouchOutside(false)
        .isCancelable(false)
        .build()

    const val splitDate1 = "至"

    /**
     * 获取当前日期 到 +days 的日期范围
     */
    fun getDateNext(days: Int): String {
        val c = Calendar.getInstance()
        c.add(Calendar.DATE, days)
        val startDate = DateUtils.dateToString(
            c.time,
            DateUtils.DATE_TO_STRING_SHORT_PATTERN
        )
        return startDate
    }

    fun View.setBackImage() {
        findViewById<ImageView>(R.id.titlebar_back).setImageResource(R.mipmap.icon_back_w)
    }


    fun EditText.setEndSelection() {
        if (!text.toString().isNullOrEmpty()) {
            setSelection(text.length)
        }
    }

    /**
     * 设置最大行数
     */
    fun EditText.judgeMaxLinesOnEdit(s: Editable, maxLine: Int) {
        val lines: Int = lineCount
        if (lines > maxLine) {
            var str: String = s.toString()
            val cursorStart: Int = selectionStart
            val cursorEnd: Int = selectionEnd
            str = if (cursorStart == cursorEnd && cursorStart < str.length && cursorStart >= 1) {
                str.substring(0, cursorStart - 1) + str.substring(cursorStart)
            } else {
                str.substring(0, s.length - 1)
            }
            // setText会触发afterTextChanged的递归
            setText(str)
            // setSelection用的索引不能使用str.length()否则会越界
            setSelection(text.length)
        }
    }

    /**
     * 设置最大行数
     */
    fun EditText.setMyMaxLines(maxLine: Int) {
        addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable) {
                val lines: Int = lineCount
                if (lines > maxLine) {
                    var str: String = s.toString()
                    val cursorStart: Int = selectionStart
                    val cursorEnd: Int = selectionEnd
                    str =
                        if (cursorStart == cursorEnd && cursorStart < str.length && cursorStart >= 1) {
                            str.substring(0, cursorStart - 1) + str.substring(cursorStart)
                        } else {
                            str.substring(0, s.length - 1)
                        }
                    // setText会触发afterTextChanged的递归
                    setText(str)
                    // setSelection用的索引不能使用str.length()否则会越界
                    setSelection(text.length)
                }
            }

            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }

            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

            }
        })
    }
}

/**
 * 清空所有监听
 */
fun TextView.clearTextWatchers() {
    MEditText.clearTextWatchers(this)
}

/**
 * 动态设置 文本TextSize
 */
fun TextView.textSize(size: Int) {
    val lightSp = SpannableString(text);
    lightSp.setSpan(AbsoluteSizeSpan(size, true), 0, text.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    text = lightSp;
}

fun postDelayedKotlin(run: () -> Unit, time: Long = 500) {
    Handler(Looper.getMainLooper()).postDelayed({
        run()
    }, time)
}

public const val useDefaultLoadingView = "useDefaultLoadingView" //使用默认的加载框 MProgressDialog

/**
 * 查找某容器下是否存在T类型控件 (inline竟然不能用递归),konlin的inline函数，java竟然不能调用，大写duck
 */
inline fun <reified T : View> getChildAsT(view: View): T? {
    val views = getChilds(view, arrayListOf())
    views.add(view) //自个儿可能也是
    for (i in views.indices) {
        val viewChild: View = views[i]
        //里面的1000即为需要找View的tag
        if (viewChild is T) {
            return viewChild
        }
    }
    return null
}

/**
 * 一次性找出所有子view
 */
fun getChilds(view: View, views: ArrayList<View>): ArrayList<View> {
    if (view is ViewGroup) {
        val vp = view as ViewGroup
        for (i in 0 until vp.childCount) {
            val viewChild: View = vp.getChildAt(i)
            views.add(viewChild)
            getChilds(viewChild, views)
        }
    }
    return views
}

fun getDrawable(resID: Int): Drawable? {
    return try {
        if (resID != 0)
            ContextCompat.getDrawable(BaseApplication.getInstance(), resID)
        else
            null
    } catch (e: Exception) {
        null
    }
}

fun getColor(resID: Int): Int {
    return try {
        ContextCompat.getColor(BaseApplication.getInstance(), resID)
    } catch (e: Exception) {
        0
    }
}

fun getTextSize(sizeId: Int): Float {
    return BaseApplication.getInstance().resources.getDimension(sizeId)
}

fun getColor(resID: String): Int {
    return try {
        Color.parseColor(resID)
    } catch (e: Exception) {
        0
    }
}

fun Double?.toDoubleNull(): Double {
    return this ?: 0.0
}

fun Double?.toDoubleString(): String {
    return this?.let {
        this.toDoubleMoney()
    } ?: ""
}

fun String?.toDefaultString(default: String = ""): String {
    return if (this.isNullOrEmpty()) default else this
}

/**
 * 2位小数
 */
fun Double?.toDoubleMoney(): String {
    return CommonUtils.getDecimal(this)
}

/**
 * 支票带逗号(千位分隔符)，
 */
fun Double?.toDoubleMoneyBank(): String {
    return CommonUtils.getDecimal(this).run {
        var lastIndex = length - 1
        if (contains("."))
            lastIndex = lastIndexOf(".")
        var newStr = ""
        for (i in (this.length - 1) downTo 0) {
            newStr = this[i] + newStr
            val mo = lastIndex - i
            if (i != 0 && mo > 0 && mo % 3 == 0) //整数部分，且非第一个
                newStr = ",$newStr"
        }
        newStr
    }
}

fun String?.clearSpace(): String? {
    return this?.replace(" ", "")
}

val spaceText = "\u3000" //一个中文空格
val spaceTextE = "\u2000" //半个中文空格

/**
 * 通过类（T）新建一个空的对象T
 */
fun <T> newObject(classOfT: Class<T>): T? {
    return try {
        Gson().fromJson<T>(
            "{\n" +
                    "\"trueName\":\"红建\",\n" +
                    "\"mobile\":\"88706922\"\n" +
                    "}", classOfT
        )
//        classOfT.newInstance() //反射没成功，未深究
    } catch (e: Exception) {
        null
    }
}

fun getFlavorClass(resName: Int): Class<*> {
    val name = BaseApplication.getInstance().resources.getString(resName)
    return Class.forName(name)
}

fun <T> getFlavorClassInstance(resName: Int): T {
    return getFlavorClass(resName).newInstance() as T
}

/**
 * fragment替代
 */
fun <T : Fragment> T.getInstance(bundle: Bundle? = null): T {
    arguments = bundle
    return try {
        when (javaClass.canonicalName) {
            else -> this
        }
    } catch (e: Exception) {
        this
    }
}

fun getVisibility(show: Boolean?): Int {
    return if (show == true) View.VISIBLE else View.GONE
}

fun String?.toMatchDate(): Date? {
    return DateUtils.getMatchDate(this)
}

fun String?.toMatchDateStr(outFormat: String): String? {
    return DateUtils.dateFormat(this, outFormat)
}

/**
 * 获取当前日期 到 -(days - 1) 的日期范围
 */
fun getDateRange(days: Int, c: Calendar = Calendar.getInstance()): String {
    val endDate = DateUtils.dateToString(c.time,
        DateUtils.DATE_TO_STRING_SHORT_PATTERN)
    c.add(Calendar.DATE, -(days - 1))
    val startDate = DateUtils.dateToString(c.time,
        DateUtils.DATE_TO_STRING_SHORT_PATTERN)
    return "$startDate$splitDate1$endDate"
}

fun getPinJie(str1: String?, str2: String?, regex: String = "："): String {
    return "${str1 ?: ""}${if (!str1.isNullOrEmpty() && !str2.isNullOrEmpty()) regex else ""}${str2 ?: ""}"
}

fun twoPinJie(str1: String?, str2: String?, color: Int = R.color.text_grey_light): CharSequence {
    return SpannedUtil.getSpanned(arrayListOf(
        SpannedBean(str1),
        SpannedBean(str2, textColor = getColor(color))
    ))
}

fun twoPinJieC(str1: String, str2: String?, color: Int? = null): CharSequence {
    return SpannedUtil.getSpanned(arrayListOf(SpannedBean(str1),
        SpannedBean(str2, textColor = color)
    ))
}